<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>通讯协议可视化生成器</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
            height: 100vh;
            display: flex;
            flex-direction: column;
        }
        
        .navbar {
            background-color: #343a40;
            color: white;
        }
        
        .main-container {
            display: flex;
            flex: 1;
            overflow: hidden;
        }
        
        .sidebar {
            width: 250px;
            background-color: #f8f9fa;
            border-right: 1px solid #dee2e6;
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .category-section {
            padding: 15px;
            border-bottom: 1px solid #dee2e6;
        }
        
        .protocol-elements {
            flex: 1;
            overflow-y: auto;
            padding: 15px;
        }
        
        .content {
            flex: 1;
            padding: 20px;
            overflow-y: auto;
        }
        
        .panel {
            background-color: white;
            border-radius: 8px;
            padding: 15px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }
        
        .panel-header {
            font-weight: bold;
            margin-bottom: 10px;
            padding-bottom: 5px;
            border-bottom: 1px solid #eee;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .protocol-item {
            padding: 8px;
            margin: 5px 0;
            background-color: #e9f7fe;
            border-radius: 4px;
            cursor: move;
        }
        
        .protocol-item.fixed {
            background-color: #e8f5e9;
        }
        
        .protocol-item.auto {
            background-color: #fff3e0;
        }
        
        .preview-area {
            min-height: 100px;
            border: 2px dashed #ccc;
            border-radius: 8px;
            padding: 10px;
            margin-top: 20px;
            display: flex;
            flex-wrap: wrap;
            align-items: center;
            gap: 5px;
        }
        
        .preview-item {
            padding: 8px 12px;
            border-radius: 4px;
            position: relative;
            cursor: pointer;
            text-align: center;
        }
        
        .preview-item .name {
            font-weight: bold;
        }
        
        .preview-item .type {
            font-size: 0.8em;
            color: #666;
        }
        
        .preview-item.fixed {
            background-color: #c8e6c9;
        }
        
        .preview-item.normal {
            background-color: #bbdefb;
        }
        
        .preview-item.auto {
            background-color: #ffe0b2;
        }
        
        .config-form {
            margin-top: 15px;
            padding: 10px;
            background-color: #f9f9f9;
            border-radius: 4px;
            display: none;
        }
        
        .config-form.active {
            display: block;
        }
        
        .form-group {
            margin-bottom: 10px;
        }
        
        .login-container {
            max-width: 400px;
            margin: 100px auto;
            padding: 20px;
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .protocol-list-item {
            padding: 8px;
            margin: 3px 0;
            background-color: #f0f0f0;
            border-radius: 4px;
            cursor: pointer;
            display: flex;
            justify-content: space-between;
        }
        
        .protocol-list-item.active {
            background-color: #d4edda;
        }
        
        .category-item {
            padding: 8px;
            margin: 3px 0;
            background-color: #e9ecef;
            border-radius: 4px;
            cursor: pointer;
        }
        
        .category-item.active {
            background-color: #cfe2ff;
        }
        
        .hidden {
            display: none;
        }
    </style>
</head>
<body>
    <!-- 登录页面 -->
    <div id="loginPage" class="login-container">
        <h2 class="text-center mb-4">通讯协议可视化生成器</h2>
        <ul class="nav nav-tabs mb-3" id="authTabs" role="tablist">
            <li class="nav-item" role="presentation">
                <button class="nav-link active" id="login-tab" data-bs-toggle="tab" data-bs-target="#login-tab-pane" type="button" role="tab" aria-controls="login-tab-pane" aria-selected="true">登录</button>
            </li>
            <li class="nav-item" role="presentation">
                <button class="nav-link" id="register-tab" data-bs-toggle="tab" data-bs-target="#register-tab-pane" type="button" role="tab" aria-controls="register-tab-pane" aria-selected="false">注册</button>
            </li>
        </ul>
        <div class="tab-content" id="authTabsContent">
            <div class="tab-pane fade show active" id="login-tab-pane" role="tabpanel" aria-labelledby="login-tab" tabindex="0">
                <form id="loginForm">
                    <div class="mb-3">
                        <label for="loginUsername" class="form-label">用户名</label>
                        <input type="text" class="form-control" id="loginUsername" required>
                    </div>
                    <div class="mb-3">
                        <label for="loginPassword" class="form-label">密码</label>
                        <input type="password" class="form-control" id="loginPassword" required>
                    </div>
                    <div class="d-grid">
                        <button type="submit" class="btn btn-primary">登录</button>
                    </div>
                </form>
            </div>
            <div class="tab-pane fade" id="register-tab-pane" role="tabpanel" aria-labelledby="register-tab" tabindex="0">
                <form id="registerForm">
                    <div class="mb-3">
                        <label for="registerUsername" class="form-label">用户名</label>
                        <input type="text" class="form-control" id="registerUsername" required>
                    </div>
                    <div class="mb-3">
                        <label for="registerEmail" class="form-label">邮箱</label>
                        <input type="email" class="form-control" id="registerEmail" required>
                    </div>
                    <div class="mb-3">
                        <label for="registerPassword" class="form-label">密码</label>
                        <input type="password" class="form-control" id="registerPassword" required>
                    </div>
                    <div class="mb-3">
                        <label for="registerConfirmPassword" class="form-label">确认密码</label>
                        <input type="password" class="form-control" id="registerConfirmPassword" required>
                    </div>
                    <div class="d-grid">
                        <button type="submit" class="btn btn-primary">注册</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

    <!-- 主应用页面 -->
    <div id="appPage" class="hidden">
        <!-- 导航栏 -->
        <nav class="navbar navbar-expand-lg navbar-dark">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">通讯协议可视化生成器</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarNav">
                    <ul class="navbar-nav me-auto">
                        <li class="nav-item">
                            <a class="nav-link active" href="#">首页</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" data-bs-toggle="modal" data-bs-target="#newProtocolModal">新建协议</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link" href="#" data-bs-toggle="modal" data-bs-target="#newCategoryModal">新建分类</a>
                        </li>
                    </ul>
                    <div class="d-flex">
                        <span class="navbar-text me-3">
                            欢迎，<span id="userDisplayName">用户</span>
                        </span>
                        <button id="logoutBtn" class="btn btn-outline-light btn-sm">退出</button>
                    </div>
                </div>
            </div>
        </nav>

        <!-- 主内容区 -->
        <div class="main-container">
            <!-- 左侧边栏 -->
            <div class="sidebar">
                <!-- 协议分类和列表 -->
                <div class="category-section">
                    <h5>协议管理</h5>
                    <div class="mb-2">
                        <select id="categorySelect" class="form-select form-select-sm">
                            <option value="all">所有协议</option>
                        </select>
                    </div>
                    <div id="protocolList" class="protocol-list">
                        <!-- 协议列表项将通过JavaScript动态添加 -->
                    </div>
                </div>
                
                <!-- 协议元素库 -->
                <div class="protocol-elements">
                    <h5>协议元素库</h5>
                    <div class="panel">
                        <div class="panel-header" onclick="togglePanel(this)">
                            <span>固定类型</span>
                            <span>+</span>
                        </div>
                        <div class="panel-content">
                            <div class="protocol-item fixed" draggable="true" data-type="fixed" data-name="包头" data-enname="header" data-value="0xAA">包头 (0xAA)</div>
                            <div class="protocol-item fixed" draggable="true" data-type="fixed" data-name="包尾" data-enname="footer" data-value="0x55">包尾 (0x55)</div>
                            <div class="protocol-item fixed" draggable="true" data-type="fixed" data-name="起始符" data-enname="start_flag" data-value="0x7E">起始符 (0x7E)</div>
                            <div class="protocol-item fixed" draggable="true" data-type="fixed" data-name="结束符" data-enname="end_flag" data-value="0x7F">结束符 (0x7F)</div>
                        </div>
                    </div>
                    
                    <div class="panel">
                        <div class="panel-header" onclick="togglePanel(this)">
                            <span>常规类型</span>
                            <span>+</span>
                        </div>
                        <div class="panel-content">
                            <div class="protocol-item normal" draggable="true" data-type="normal" data-name="设备ID" data-enname="device_id" data-datatype="uint8">设备ID (uint8)</div>
                            <div class="protocol-item normal" draggable="true" data-type="normal" data-name="温度值" data-enname="temperature" data-datatype="int16">温度值 (int16)</div>
                            <div class="protocol-item normal" draggable="true" data-type="normal" data-name="湿度值" data-enname="humidity" data-datatype="float">湿度值 (float)</div>
                            <div class="protocol-item normal" draggable="true" data-type="normal" data-name="状态位" data-enname="status" data-datatype="bits">状态位 (bits)</div>
                            <div class="protocol-item normal" draggable="true" data-type="normal" data-name="经度" data-enname="longitude" data-datatype="double">经度 (double)</div>
                        </div>
                    </div>
                    
                    <div class="panel">
                        <div class="panel-header" onclick="togglePanel(this)">
                            <span>自动计算类型</span>
                            <span>+</span>
                        </div>
                        <div class="panel-content">
                            <div class="protocol-item auto" draggable="true" data-type="auto" data-name="长度" data-enname="length" data-calctype="length">长度 (自动计算)</div>
                            <div class="protocol-item auto" draggable="true" data-type="auto" data-name="校验和" data-enname="checksum" data-calctype="checksum">校验和</div>
                            <div class="protocol-item auto" draggable="true" data-type="auto" data-name="CRC8" data-enname="crc8" data-calctype="crc8">CRC8</div>
                            <div class="protocol-item auto" draggable="true" data-type="auto" data-name="CRC16" data-enname="crc16" data-calctype="crc16">CRC16</div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 主内容区 -->
            <div class="content">
                <div class="panel">
                    <h4 id="currentProtocolName">协议预览与配置</h4>
                    <div class="preview-area" id="previewArea"></div>
                    
                    <div class="config-form" id="configForm">
                        <h5>配置项</h5>
                        <div id="formContent"></div>
                        <div class="button-group mt-3">
                            <button class="btn btn-primary btn-sm" onclick="saveConfig()">保存</button>
                            <button class="btn btn-secondary btn-sm" onclick="moveUp()">上移</button>
                            <button class="btn btn-secondary btn-sm" onclick="moveDown()">下移</button>
                            <button class="btn btn-danger btn-sm" onclick="removeItem()">删除</button>
                        </div>
                    </div>
                    
                    <div class="mt-3">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" id="hexDisplay">
                            <label class="form-check-label" for="hexDisplay">
                                16进制显示
                            </label>
                        </div>
                    </div>
                    
                    <div class="mt-4">
                        <h5>导出选项</h5>
                        <div class="row">
                            <div class="col-md-6">
                                <select id="exportType" class="form-select mb-2">
                                    <option value="c-header">C语言头文件</option>
                                    <option value="c-source">C语言源文件</option>
                                    <option value="python">Python字典</option>
                                </select>
                            </div>
                            <div class="col-md-6">
                                <button class="btn btn-success" onclick="exportCode()">导出代码</button>
                            </div>
                        </div>
                        
                        <div id="codeOutput" class="mt-3 p-3 bg-light rounded" style="display: none;">
                            <pre id="generatedCode" class="mb-0"></pre>
                            <div class="mt-2">
                                <button class="btn btn-sm btn-outline-secondary" onclick="copyCode()">复制代码</button>
                                <button class="btn btn-sm btn-outline-primary" onclick="downloadCode()">下载文件</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- 新建协议模态框 -->
    <div class="modal fade" id="newProtocolModal" tabindex="-1" aria-labelledby="newProtocolModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="newProtocolModalLabel">新建协议</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="newProtocolForm">
                        <div class="mb-3">
                            <label for="protocolName" class="form-label">协议名称</label>
                            <input type="text" class="form-control" id="protocolName" required>
                        </div>
                        <div class="mb-3">
                            <label for="protocolDescription" class="form-label">协议描述</label>
                            <textarea class="form-control" id="protocolDescription" rows="3"></textarea>
                        </div>
                        <div class="mb-3">
                            <label for="protocolCategory" class="form-label">所属分类</label>
                            <select class="form-select" id="protocolCategory">
                                <option value="">无分类</option>
                                <!-- 分类选项将通过JavaScript动态添加 -->
                            </select>
                        </div>
                        <div class="form-check mb-3">
                            <input class="form-check-input" type="checkbox" id="protocolIsPublic">
                            <label class="form-check-label" for="protocolIsPublic">
                                公开协议
                            </label>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" id="saveProtocolBtn">保存</button>
                </div>
            </div>
        </div>
    </div>

    <!-- 新建分类模态框 -->
    <div class="modal fade" id="newCategoryModal" tabindex="-1" aria-labelledby="newCategoryModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="newCategoryModalLabel">新建分类</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="newCategoryForm">
                        <div class="mb-3">
                            <label for="categoryName" class="form-label">分类名称</label>
                            <input type="text" class="form-control" id="categoryName" required>
                        </div>
                        <div class="mb-3">
                            <label for="categoryDescription" class="form-label">分类描述</label>
                            <textarea class="form-control" id="categoryDescription" rows="3"></textarea>
                        </div>
                        <div class="form-check mb-3">
                            <input class="form-check-input" type="checkbox" id="categoryIsPublic">
                            <label class="form-check-label" for="categoryIsPublic">
                                公开分类
                            </label>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                    <button type="button" class="btn btn-primary" id="saveCategoryBtn">保存</button>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 全局变量
        let protocolItems = [];
        let selectedIndex = -1;
        let currentProtocolId = null;
        let currentCategoryId = null;
        let authToken = null;
        let currentUser = null;
        
        // API基础URL
        const API_BASE_URL = 'http://localhost:3000/api';
        
        // 页面加载完成后执行
        document.addEventListener('DOMContentLoaded', function() {
            // 检查是否已登录
            checkAuthStatus();
            
            // 初始化登录表单
            document.getElementById('loginForm').addEventListener('submit', function(e) {
                e.preventDefault();
                login();
            });
            
            // 初始化注册表单
            document.getElementById('registerForm').addEventListener('submit', function(e) {
                e.preventDefault();
                register();
            });
            
            // 初始化退出按钮
            document.getElementById('logoutBtn').addEventListener('click', logout);
            
            // 初始化新建协议按钮
            document.getElementById('saveProtocolBtn').addEventListener('click', createProtocol);
            
            // 初始化新建分类按钮
            document.getElementById('saveCategoryBtn').addEventListener('click', createCategory);
            
            // 初始化分类选择器
            document.getElementById('categorySelect').addEventListener('change', function() {
                currentCategoryId = this.value === 'all' ? null : this.value;
                loadProtocols();
            });
        });
        
        // 检查认证状态
        function checkAuthStatus() {
            const token = localStorage.getItem('authToken');
            if (token) {
                authToken = token;
                fetchCurrentUser();
            } else {
                showLoginPage();
            }
        }
        
        // 显示登录页面
        function showLoginPage() {
            document.getElementById('loginPage').classList.remove('hidden');
            document.getElementById('appPage').classList.add('hidden');
        }
        
        // 显示应用页面
        function showAppPage() {
            document.getElementById('loginPage').classList.add('hidden');
            document.getElementById('appPage').classList.remove('hidden');
            
            // 初始化应用
            initApp();
        }
        
        // 初始化应用
        function initApp() {
            // 加载分类
            loadCategories();
            
            // 加载协议
            loadProtocols();
            
            // 初始化拖拽功能
            initDragDrop();
            
            // 默认展开第一个面板
            document.querySelector('.panel-header').click();
        }
        
        // 登录
        async function login() {
            const username = document.getElementById('loginUsername').value;
            const password = document.getElementById('loginPassword').value;
            
            try {
                const response = await fetch(`${API_BASE_URL}/auth/login`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ username, password })
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    // 保存认证令牌
                    localStorage.setItem('authToken', data.token);
                    authToken = data.token;
                    currentUser = data.user;
                    
                    // 显示应用页面
                    showAppPage();
                    
                    // 显示用户名
                    document.getElementById('userDisplayName').textContent = currentUser.username;
                } else {
                    alert(data.message || '登录失败');
                }
            } catch (error) {
                console.error('登录失败:', error);
                alert('登录失败，请稍后重试');
            }
        }
        
        // 注册
        async function register() {
            const username = document.getElementById('registerUsername').value;
            const email = document.getElementById('registerEmail').value;
            const password = document.getElementById('registerPassword').value;
            const confirmPassword = document.getElementById('registerConfirmPassword').value;
            
            // 验证密码
            if (password !== confirmPassword) {
                alert('两次输入的密码不一致');
                return;
            }
            
            try {
                const response = await fetch(`${API_BASE_URL}/auth/register`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ username, email, password })
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    alert('注册成功，请登录');
                    
                    // 切换到登录标签
                    const loginTab = document.getElementById('login-tab');
                    const bsTab = new bootstrap.Tab(loginTab);
                    bsTab.show();
                    
                    // 清空注册表单
                    document.getElementById('registerForm').reset();
                } else {
                    alert(data.message || '注册失败');
                }
            } catch (error) {
                console.error('注册失败:', error);
                alert('注册失败，请稍后重试');
            }
        }
        
        // 获取当前用户信息
        async function fetchCurrentUser() {
            try {
                const response = await fetch(`${API_BASE_URL}/auth/me`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (response.ok) {
                    const data = await response.json();
                    currentUser = data.user;
                    
                    // 显示应用页面
                    showAppPage();
                    
                    // 显示用户名
                    document.getElementById('userDisplayName').textContent = currentUser.username;
                } else {
                    // 认证失败，清除令牌
                    localStorage.removeItem('authToken');
                    authToken = null;
                    showLoginPage();
                }
            } catch (error) {
                console.error('获取用户信息失败:', error);
                // 认证失败，清除令牌
                localStorage.removeItem('authToken');
                authToken = null;
                showLoginPage();
            }
        }
        
        // 退出登录
        function logout() {
            // 清除认证令牌
            localStorage.removeItem('authToken');
            authToken = null;
            currentUser = null;
            
            // 显示登录页面
            showLoginPage();
        }
        
        // 加载分类
        async function loadCategories() {
            try {
                const response = await fetch(`${API_BASE_URL}/categories`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (response.ok) {
                    const data = await response.json();
                    
                    // 更新分类选择器
                    const categorySelect = document.getElementById('categorySelect');
                    const protocolCategory = document.getElementById('protocolCategory');
                    
                    // 清空现有选项，保留"所有协议"选项
                    categorySelect.innerHTML = '<option value="all">所有协议</option>';
                    protocolCategory.innerHTML = '<option value="">无分类</option>';
                    
                    // 添加分类选项
                    data.categories.forEach(category => {
                        const option1 = document.createElement('option');
                        option1.value = category.id;
                        option1.textContent = category.name;
                        categorySelect.appendChild(option1);
                        
                        const option2 = document.createElement('option');
                        option2.value = category.id;
                        option2.textContent = category.name;
                        protocolCategory.appendChild(option2);
                    });
                } else {
                    console.error('加载分类失败');
                }
            } catch (error) {
                console.error('加载分类失败:', error);
            }
        }
        
        // 加载协议
        async function loadProtocols() {
            try {
                let url = `${API_BASE_URL}/protocols`;
                if (currentCategoryId && currentCategoryId !== 'all') {
                    url = `${API_BASE_URL}/protocols/category/${currentCategoryId}`;
                }
                
                const response = await fetch(url, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (response.ok) {
                    const data = await response.json();
                    
                    // 更新协议列表
                    const protocolList = document.getElementById('protocolList');
                    protocolList.innerHTML = '';
                    
                    // 添加协议项
                    data.protocols.forEach(protocol => {
                        const item = document.createElement('div');
                        item.className = `protocol-list-item ${protocol.id === currentProtocolId ? 'active' : ''}`;
                        item.innerHTML = `
                            <span>${protocol.name}</span>
                            <span>${protocol.category_name || '无分类'}</span>
                        `;
                        
                        item.addEventListener('click', () => {
                            loadProtocol(protocol.id);
                        });
                        
                        protocolList.appendChild(item);
                    });
                    
                    // 如果没有选中的协议，选择第一个
                    if (!currentProtocolId && data.protocols.length > 0) {
                        loadProtocol(data.protocols[0].id);
                    }
                } else {
                    console.error('加载协议失败');
                }
            } catch (error) {
                console.error('加载协议失败:', error);
            }
        }
        
        // 加载协议详情
        async function loadProtocol(protocolId) {
            try {
                const response = await fetch(`${API_BASE_URL}/protocols/${protocolId}`, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (response.ok) {
                    const data = await response.json();
                    
                    // 更新当前协议ID
                    currentProtocolId = protocolId;
                    
                    // 更新协议名称
                    document.getElementById('currentProtocolName').textContent = data.protocol.name;
                    
                    // 更新协议列表项的活动状态
                    const items = document.querySelectorAll('.protocol-list-item');
                    items.forEach(item => {
                        item.classList.remove('active');
                    });
                    
                    const activeItems = document.querySelectorAll(`.protocol-list-item[data-id="${protocolId}"]`);
                    activeItems.forEach(item => {
                        item.classList.add('active');
                    });
                    
                    // 清空预览区域
                    clearPreviewArea();
                    
                    // 添加协议元素
                    const previewArea = document.getElementById('previewArea');
                    data.elements.forEach(element => {
                        const previewItem = document.createElement('div');
                        previewItem.className = `preview-item ${element.element_type}`;
                        previewItem.dataset.id = element.id;
                        previewItem.dataset.type = element.element_type;
                        previewItem.dataset.name = element.name;
                        previewItem.dataset.enname = element.en_name;
                        
                        if (element.element_type === 'fixed') {
                            previewItem.dataset.value = element.value;
                            previewItem.innerHTML = `
                                <div class="name">${element.name}</div>
                                <div class="type">固定值: ${element.value}</div>
                            `;
                        } else if (element.element_type === 'normal') {
                            previewItem.dataset.datatype = element.data_type;
                            previewItem.innerHTML = `
                                <div class="name">${element.name}</div>
                                <div class="type">${getDataTypeText(element.data_type)}</div>
                            `;
                        } else if (element.element_type === 'auto') {
                            previewItem.dataset.calctype = element.calc_type;
                            previewItem.innerHTML = `
                                <div class="name">${element.name}</div>
                                <div class="type">${getCalcTypeText(element.calc_type)}</div>
                            `;
                        }
                        
                        previewItem.addEventListener('click', function() {
                            selectItem(this);
                        });
                        
                        previewArea.appendChild(previewItem);
                    });
                    
                    // 更新协议项数组
                    updateProtocolItems();
                } else {
                    console.error('加载协议详情失败');
                }
            } catch (error) {
                console.error('加载协议详情失败:', error);
            }
        }
        
        // 创建协议
        async function createProtocol() {
            const name = document.getElementById('protocolName').value;
            const description = document.getElementById('protocolDescription').value;
            const categoryId = document.getElementById('protocolCategory').value;
            const isPublic = document.getElementById('protocolIsPublic').checked;
            
            if (!name) {
                alert('请输入协议名称');
                return;
            }
            
            try {
                const response = await fetch(`${API_BASE_URL}/protocols`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${authToken}`
                    },
                    body: JSON.stringify({
                        name,
                        description,
                        categoryId: categoryId || null,
                        isPublic
                    })
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    // 关闭模态框
                    const modal = bootstrap.Modal.getInstance(document.getElementById('newProtocolModal'));
                    modal.hide();
                    
                    // 重置表单
                    document.getElementById('newProtocolForm').reset();
                    
                    // 重新加载协议列表
                    loadProtocols();
                    
                    // 加载新创建的协议
                    loadProtocol(data.protocol.id);
                } else {
                    alert(data.message || '创建协议失败');
                }
            } catch (error) {
                console.error('创建协议失败:', error);
                alert('创建协议失败，请稍后重试');
            }
        }
        
        // 创建分类
        async function createCategory() {
            const name = document.getElementById('categoryName').value;
            const description = document.getElementById('categoryDescription').value;
            const isPublic = document.getElementById('categoryIsPublic').checked;
            
            if (!name) {
                alert('请输入分类名称');
                return;
            }
            
            try {
                const response = await fetch(`${API_BASE_URL}/categories`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${authToken}`
                    },
                    body: JSON.stringify({
                        name,
                        description,
                        isPublic
                    })
                });
                
                const data = await response.json();
                
                if (response.ok) {
                    // 关闭模态框
                    const modal = bootstrap.Modal.getInstance(document.getElementById('newCategoryModal'));
                    modal.hide();
                    
                    // 重置表单
                    document.getElementById('newCategoryForm').reset();
                    
                    // 重新加载分类列表
                    loadCategories();
                } else {
                    alert(data.message || '创建分类失败');
                }
            } catch (error) {
                console.error('创建分类失败:', error);
                alert('创建分类失败，请稍后重试');
            }
        }
        
        // 初始化拖拽功能
        function initDragDrop() {
            const protocolItems = document.querySelectorAll('.protocol-item');
            const previewArea = document.getElementById('previewArea');
            
            protocolItems.forEach(item => {
                item.addEventListener('dragstart', function(e) {
                    e.dataTransfer.setData('text/plain', this.outerHTML);
                    e.dataTransfer.setData('type', this.dataset.type);
                });
            });
            
            previewArea.addEventListener('dragover', function(e) {
                e.preventDefault();
            });
            
            previewArea.addEventListener('drop', function(e) {
                e.preventDefault();
                const html = e.dataTransfer.getData('text/plain');
                const type = e.dataTransfer.getData('type');
                
                const temp = document.createElement('div');
                temp.innerHTML = html;
                const newItem = temp.firstChild;
                
                const rect = previewArea.getBoundingClientRect();
                const x = e.clientX - rect.left;
                
                // 找到插入位置
                const children = Array.from(previewArea.children);
                let insertBeforeIndex = children.findIndex(child => {
                    const childRect = child.getBoundingClientRect();
                    return x < childRect.left + childRect.width / 2 - rect.left;
                });
                
                if (insertBeforeIndex === -1) {
                    previewArea.appendChild(createPreviewItem(newItem));
                } else {
                    previewArea.insertBefore(createPreviewItem(newItem), children[insertBeforeIndex]);
                }
                
                updateProtocolItems();
                saveProtocolElements();
            });
        }
        
        // 创建预览项
        function createPreviewItem(item) {
            if (!item || !item.dataset) {
                console.error('Invalid item provided to createPreviewItem:', item);
                return document.createElement('div'); // 返回一个空的div作为安全措施
            }

            const previewItem = document.createElement('div');
            const type = item.dataset.type || 'normal'; // 提供默认值
            
            previewItem.className = `preview-item ${type}`;
            previewItem.dataset.type = type;
            previewItem.dataset.name = item.dataset.name || '';
            previewItem.dataset.enname = item.dataset.enname || '';
            
            if (type === 'fixed') {
                previewItem.dataset.value = item.dataset.value;
                previewItem.innerHTML = `
                    <div class="name">${item.dataset.name}</div>
                    <div class="type">固定值: ${item.dataset.value}</div>
                `;
            } else if (type === 'normal') {
                previewItem.dataset.datatype = item.dataset.datatype;
                previewItem.innerHTML = `
                    <div class="name">${item.dataset.name}</div>
                    <div class="type">${getDataTypeText(item.dataset.datatype)}</div>
                `;
            } else if (type === 'auto') {
                previewItem.dataset.calctype = item.dataset.calctype;
                previewItem.innerHTML = `
                    <div class="name">${item.dataset.name}</div>
                    <div class="type">${getCalcTypeText(item.dataset.calctype)}</div>
                `;
            }
            
            previewItem.addEventListener('click', function() {
                selectItem(this);
            });
            
            return previewItem;
        }
        
        // 获取数据类型文本
        function getDataTypeText(type) {
            const types = {
                'uint8': '无符号8位',
                'int8': '有符号8位',
                'int16': '有符号16位',
                'uint16': '无符号16位',
                'float': '单精度浮点',
                'double': '双精度浮点',
                'bits': '位域'
            };
            return types[type] || type;
        }
        
        // 获取计算类型文本
        function getCalcTypeText(type) {
            const types = {
                'length': '长度计算',
                'checksum': '校验和',
                'crc8': 'CRC8',
                'crc16': 'CRC16'
            };
            return types[type] || type;
        }
        
        // 选择项目
        function selectItem(item) {
            const items = document.querySelectorAll('.preview-item');
            items.forEach(i => i.style.border = 'none');
            
            item.style.border = '2px solid #2196F3';
            selectedIndex = Array.from(items).indexOf(item);
            
            showConfigForm(item);
        }
        
        // 显示配置表单
        function showConfigForm(item) {
            const formContent = document.getElementById('formContent');
            formContent.innerHTML = '';
            
            const type = item.dataset.type;
            const configForm = document.getElementById('configForm');
            
            if (type === 'fixed') {
                formContent.innerHTML = `
                    <div class="mb-3">
                        <label class="form-label">中文名称</label>
                        <input type="text" class="form-control" id="configName" value="${item.dataset.name}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">英文名称</label>
                        <input type="text" class="form-control" id="configEnName" value="${item.dataset.enname}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">值</label>
                        <input type="text" class="form-control" id="configValue" value="${item.dataset.value}">
                    </div>
                `;
            } else if (type === 'normal') {
                const dataType = item.dataset.datatype;
                formContent.innerHTML = `
                    <div class="mb-3">
                        <label class="form-label">中文名称</label>
                        <input type="text" class="form-control" id="configName" value="${item.dataset.name}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">英文名称</label>
                        <input type="text" class="form-control" id="configEnName" value="${item.dataset.enname}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">数据类型</label>
                        <select class="form-select" id="configDataType">
                            <option value="uint8" ${dataType === 'uint8' ? 'selected' : ''}>无符号8位</option>
                            <option value="int8" ${dataType === 'int8' ? 'selected' : ''}>有符号8位</option>
                            <option value="uint16" ${dataType === 'uint16' ? 'selected' : ''}>无符号16位</option>
                            <option value="int16" ${dataType === 'int16' ? 'selected' : ''}>有符号16位</option>
                            <option value="float" ${dataType === 'float' ? 'selected' : ''}>单精度浮点</option>
                            <option value="double" ${dataType === 'double' ? 'selected' : ''}>双精度浮点</option>
                            <option value="bits" ${dataType === 'bits' ? 'selected' : ''}>位域</option>
                        </select>
                    </div>
                `;
            } else if (type === 'auto') {
                const calcType = item.dataset.calctype;
                formContent.innerHTML = `
                    <div class="mb-3">
                        <label class="form-label">中文名称</label>
                        <input type="text" class="form-control" id="configName" value="${item.dataset.name}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">英文名称</label>
                        <input type="text" class="form-control" id="configEnName" value="${item.dataset.enname}">
                    </div>
                    <div class="mb-3">
                        <label class="form-label">计算类型</label>
                        <select class="form-select" id="configCalcType">
                            <option value="length" ${calcType === 'length' ? 'selected' : ''}>长度计算</option>
                            <option value="checksum" ${calcType === 'checksum' ? 'selected' : ''}>校验和</option>
                            <option value="crc8" ${calcType === 'crc8' ? 'selected' : ''}>CRC8</option>
                            <option value="crc16" ${calcType === 'crc16' ? 'selected' : ''}>CRC16</option>
                        </select>
                    </div>
                `;
            }
            
            configForm.classList.add('active');
        }
        
        // 保存配置
        function saveConfig() {
            if (selectedIndex === -1) return;
            
            const items = document.querySelectorAll('.preview-item');
            const item = items[selectedIndex];
            const type = item.dataset.type;
            
            if (type === 'fixed') {
                const name = document.getElementById('configName').value;
                const enname = document.getElementById('configEnName').value;
                const value = document.getElementById('configValue').value;
                
                item.dataset.name = name;
                item.dataset.enname = enname;
                item.dataset.value = value;
                item.innerHTML = `
                    <div class="name">${name}</div>
                    <div class="type">固定值: ${value}</div>
                `;
            } else if (type === 'normal') {
                const name = document.getElementById('configName').value;
                const enname = document.getElementById('configEnName').value;
                const dataType = document.getElementById('configDataType').value;
                
                item.dataset.name = name;
                item.dataset.enname = enname;
                item.dataset.datatype = dataType;
                item.innerHTML = `
                    <div class="name">${name}</div>
                    <div class="type">${getDataTypeText(dataType)}</div>
                `;
            } else if (type === 'auto') {
                const name = document.getElementById('configName').value;
                const enname = document.getElementById('configEnName').value;
                const calcType = document.getElementById('configCalcType').value;
                
                item.dataset.name = name;
                item.dataset.enname = enname;
                item.dataset.calctype = calcType;
                item.innerHTML = `
                    <div class="name">${name}</div>
                    <div class="type">${getCalcTypeText(calcType)}</div>
                `;
            }
            
            updateProtocolItems();
            saveProtocolElements();
        }
        
        // 上移项目
        function moveUp() {
            if (selectedIndex <= 0) return;
            
            const previewArea = document.getElementById('previewArea');
            const items = Array.from(previewArea.children);
            
            if (selectedIndex > 0) {
                const item = items[selectedIndex];
                previewArea.insertBefore(item, items[selectedIndex - 1]);
                selectedIndex--;
                updateProtocolItems();
                saveProtocolElements();
            }
        }
        
        // 下移项目
        function moveDown() {
            const previewArea = document.getElementById('previewArea');
            const items = Array.from(previewArea.children);
            
            if (selectedIndex < items.length - 1) {
                const item = items[selectedIndex];
                previewArea.insertBefore(item, items[selectedIndex + 2] || null);
                selectedIndex++;
                updateProtocolItems();
                saveProtocolElements();
            }
        }
        
        // 删除项目
        function removeItem() {
            if (selectedIndex === -1) return;
            
            const previewArea = document.getElementById('previewArea');
            const items = Array.from(previewArea.children);
            const item = items[selectedIndex];
            
            // 如果元素有ID，则从服务器删除
            if (item.dataset.id) {
                deleteProtocolElement(item.dataset.id);
            }
            
            previewArea.removeChild(item);
            document.getElementById('configForm').classList.remove('active');
            selectedIndex = -1;
            updateProtocolItems();
            saveProtocolElements();
        }
        
        // 更新协议项目数组
        function updateProtocolItems() {
            const previewArea = document.getElementById('previewArea');
            protocolItems = Array.from(previewArea.children).map((item, index) => {
                return {
                    id: item.dataset.id,
                    type: item.dataset.type,
                    name: item.dataset.name,
                    enname: item.dataset.enname,
                    value: item.dataset.value,
                    datatype: item.dataset.datatype,
                    calctype: item.dataset.calctype,
                    position: index
                };
            });
        }
        
        // 保存协议元素
        async function saveProtocolElements() {
            if (!currentProtocolId) return;
            
            try {
                // 遍历所有元素，添加或更新
                for (const item of protocolItems) {
                    if (item.id) {
                        // 更新现有元素
                        await updateProtocolElement(item);
                    } else {
                        // 添加新元素
                        await addProtocolElement(item);
                    }
                }
            } catch (error) {
                console.error('保存协议元素失败:', error);
                alert('保存协议元素失败，请稍后重试');
            }
        }
        
        // 添加协议元素
        async function addProtocolElement(item) {
            try {
                const response = await fetch(`${API_BASE_URL}/protocols/${currentProtocolId}/elements`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${authToken}`
                    },
                    body: JSON.stringify({
                        name: item.name,
                        enName: item.enname,
                        elementType: item.type,
                        position: item.position,
                        value: item.value,
                        dataType: item.datatype,
                        calcType: item.calctype
                    })
                });
                
                if (response.ok) {
                    // 重新加载协议
                    loadProtocol(currentProtocolId);
                } else {
                    console.error('添加协议元素失败');
                }
            } catch (error) {
                console.error('添加协议元素失败:', error);
                throw error;
            }
        }
        
        // 更新协议元素
        async function updateProtocolElement(item) {
            try {
                const response = await fetch(`${API_BASE_URL}/protocols/${currentProtocolId}/elements/${item.id}`, {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${authToken}`
                    },
                    body: JSON.stringify({
                        name: item.name,
                        enName: item.enname,
                        position: item.position,
                        value: item.value,
                        dataType: item.datatype,
                        calcType: item.calctype
                    })
                });
                
                if (!response.ok) {
                    console.error('更新协议元素失败');
                }
            } catch (error) {
                console.error('更新协议元素失败:', error);
                throw error;
            }
        }
        
        // 删除协议元素
        async function deleteProtocolElement(elementId) {
            try {
                const response = await fetch(`${API_BASE_URL}/protocols/${currentProtocolId}/elements/${elementId}`, {
                    method: 'DELETE',
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (!response.ok) {
                    console.error('删除协议元素失败');
                }
            } catch (error) {
                console.error('删除协议元素失败:', error);
            }
        }
        
        // 导出代码
        async function exportCode() {
            if (!currentProtocolId) {
                alert('请先选择一个协议');
                return;
            }
            
            const exportType = document.getElementById('exportType').value;
            let url;
            let fileName;
            
            if (exportType === 'c-header') {
                url = `${API_BASE_URL}/generator/${currentProtocolId}/c-header`;
                fileName = 'protocol.h';
            } else if (exportType === 'c-source') {
                url = `${API_BASE_URL}/generator/${currentProtocolId}/c-source`;
                fileName = 'protocol.c';
            } else {
                alert('暂不支持此导出类型');
                return;
            }
            
            try {
                const response = await fetch(url, {
                    headers: {
                        'Authorization': `Bearer ${authToken}`
                    }
                });
                
                if (response.ok) {
                    const data = await response.json();
                    
                    // 显示生成的代码
                    document.getElementById('generatedCode').textContent = data.code;
                    document.getElementById('codeOutput').style.display = 'block';
                    
                    // 更新文件名
                    fileName = data.fileName;
                } else {
                    alert('导出代码失败');
                }
            } catch (error) {
                console.error('导出代码失败:', error);
                alert('导出代码失败，请稍后重试');
            }
        }
        
        // 复制代码
        function copyCode() {
            const code = document.getElementById('generatedCode').textContent;
            navigator.clipboard.writeText(code)
                .then(() => {
                    alert('代码已复制到剪贴板');
                })
                .catch(err => {
                    console.error('复制失败:', err);
                    alert('复制失败，请手动复制');
                });
        }
        
        // 下载代码文件
        function downloadCode() {
            const code = document.getElementById('generatedCode').textContent;
            const exportType = document.getElementById('exportType').value;
            let fileName;
            
            if (exportType === 'c-header') {
                fileName = 'protocol.h';
            } else if (exportType === 'c-source') {
                fileName = 'protocol.c';
            } else {
                fileName = 'protocol.txt';
            }
            
            const blob = new Blob([code], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = fileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(url);
        }
        
        // 清空预览区域
        function clearPreviewArea() {
            const previewArea = document.getElementById('previewArea');
            previewArea.innerHTML = '';
            protocolItems = [];
            selectedIndex = -1;
            document.getElementById('configForm').classList.remove('active');
        }
        
        // 切换面板展开/折叠
        function togglePanel(header) {
            const panel = header.parentElement;
            const content = panel.querySelector('.panel-content');
            
            if (content.style.display === 'none' || !content.style.display) {
                content.style.display = 'block';
                header.querySelector('span:last-child').textContent = '-';
            } else {
                content.style.display = 'none';
                header.querySelector('span:last-child').textContent = '+';
            }
        }
    </script>
</body>
</html>
